home *** CD-ROM | disk | FTP | other *** search
- # Source Generated with Decompyle++
- # File: in.pyc (Python 2.4)
-
- from __future__ import division
- import re
- import sys
- import types
- import images
- import string
- import locale
- import textwrap
- import wx
- import wx.lib.buttons as wx
- import wx.lib.hyperlink as hl
- import wx.lib.mixins.listctrl as listmix
- from spamexperts.Options import options
-
- def progress_update_wrapper(dlg):
-
- def update(*args):
- dlg.Update(*args)
- (new_w, new_h) = dlg.GetBestSize()
- (w, h) = dlg.GetSize()
- dlg.SetSize((max(w, new_w), max(new_h, h)))
-
- return update
-
-
- def wrap(s, length = 70):
- '''A simple wordwrap function. Provides more natural results
- than textwrap.wrap().'''
- line = ''
- lines = []
- for word in s.split(' '):
- if '\n' in word:
- parts = word.split('\n')
- if len(line) + len(parts[0]) <= length:
- line += parts[0]
- parts = parts[1:]
-
- lines.append(line)
- line = parts[-1] + ' '
- continue
- None if len(parts) > 1 else []
- if len(line) + len(word) <= length:
- line += word + ' '
- continue
- lines.append(line[:-1])
- line = word + ' '
-
- lines.append(line)
- return lines
-
-
- def fill(s, length = 70):
- return '\n'.join(wrap(s, length))
-
-
- class DigitValidator(wx.PyValidator):
- valid_characters = string.digits
-
- def __init__(self):
- wx.PyValidator.__init__(self)
- self.Bind(wx.EVT_CHAR, self.OnChar)
-
-
- def Clone(self):
- return DigitValidator()
-
-
- def Validate(self, win):
- tc = self.GetWindow()
- val = tc.GetValue()
- for x in val:
- if x not in self.valid_characters:
- return False
- continue
-
- return True
-
-
- def OnChar(self, event):
- key = event.KeyCode()
- if key in [
- wx.WXK_BACK,
- wx.WXK_DELETE] or key > 255:
- event.Skip()
- return None
-
- if chr(key) in self.valid_characters:
- event.Skip()
- return None
-
- if not wx.Validator_IsSilent():
- wx.Bell()
-
-
-
-
- class DigitsValidator(DigitValidator):
- valid_characters = string.digits + ','
-
- def Clone(self):
- return DigitsValidator()
-
-
-
- class AutoWidthSortedLC(wx.ListCtrl, listmix.ColumnSorterMixin):
-
- def __init__(self, parent, style = wx.LC_REPORT | wx.LC_SORT_ASCENDING | wx.LC_VRULES | wx.LC_HRULES, nocols = 6):
- wx.ListCtrl.__init__(self, parent, style = style)
- listmix.ColumnSorterMixin.__init__(self, nocols)
- self.il = wx.ImageList(16, 16)
- self.sm_up = self.il.Add(images.getSmallUpArrowBitmap())
- self.sm_dn = self.il.Add(images.getSmallDnArrowBitmap())
- self.SetImageList(self.il, wx.IMAGE_LIST_SMALL)
- self.place = None
- self.active_item = 0
-
-
- def DeselectAll(self):
- self.selecting = True
- for i in range(self.GetItemCount()):
- self.SetItemState(i, 0, wx.LIST_STATE_SELECTED)
-
- self.selecting = False
-
-
- def GetListCtrl(self):
- return self
-
-
- def GetSortImages(self):
- return (self.sm_dn, self.sm_up)
-
-
- def GetColumnSorter(self):
- '''Returns a callable object to be used for comparing column values when sorting.'''
- return self._AutoWidthSortedLC__ColumnSorter
-
-
- def __ColumnSorter(self, key1, key2):
- '''Like the wx.lib.mixins.listctrl.ColumnSorterMixin method, but
- case insensitive.'''
- col = self._col
- ascending = self._colSortFlag[col]
- item1 = self.itemDataMap[key1]
- item2 = self.itemDataMap[key2]
- if type(item1) == type('') or type(item2) == type(''):
- cmpVal = locale.strcoll(str(item1).lower(), str(item2).lower())
- else:
- cmpVal = cmp(item1, item2)
- if cmpVal == 0:
- cmpVal = apply(cmp, self.GetSecondarySortValues(col, key1, key2))
-
- if ascending:
- return cmpVal
- else:
- return -cmpVal
-
-
- def MoveSelectionUp(self, deselect = True):
- if self.place is None:
- self.place = self.GetFocusedItem()
-
- next = self.GetNextItem(self.GetFocusedItem(), wx.LIST_NEXT_ABOVE)
- self.active_item = next
- if next > -1:
- self.DeselectAll()
- if deselect:
- self.place = None
- self.Select(next)
-
- self.Focus(next)
- self.EnsureVisible(next)
- if self.place is not None:
- start = min(self.place, self.GetFocusedItem())
- stop = max(self.place, self.GetFocusedItem()) + 1
- for i in xrange(start, stop):
- self.Select(i)
-
-
-
-
-
- def MoveSelectionDown(self, deselect = True):
- if self.place is None:
- self.place = self.GetFocusedItem()
-
- next = self.GetNextItem(self.GetFocusedItem(), wx.LIST_NEXT_BELOW)
- self.active_item = next
- if next > -1:
- self.DeselectAll()
- if deselect:
- self.place = None
- self.Select(next)
-
- self.Focus(next)
- self.EnsureVisible(next)
- if self.place is not None:
- start = min(self.place, self.GetFocusedItem())
- stop = max(self.place, self.GetFocusedItem()) + 1
- for i in xrange(start, stop):
- self.Select(i)
-
-
-
-
-
-
- class SortedLC(wx.ListCtrl, listmix.ColumnSorterMixin):
-
- def __init__(self, parent, style = wx.LC_REPORT | wx.LC_SORT_ASCENDING | wx.LC_VRULES | wx.LC_HRULES, nocols = 6):
- wx.ListCtrl.__init__(self, parent, style = style)
- self.itemDataMap = []
- listmix.ColumnSorterMixin.__init__(self, nocols)
- self.il = wx.ImageList(16, 16)
- self.sm_up = self.il.Add(images.getSmallUpArrowBitmap())
- self.sm_dn = self.il.Add(images.getSmallDnArrowBitmap())
- self.SetImageList(self.il, wx.IMAGE_LIST_SMALL)
- self.place = None
- self.active_item = 0
-
-
- def DeselectAll(self):
- self.selecting = True
- for i in range(self.GetItemCount()):
- self.SetItemState(i, 0, wx.LIST_STATE_SELECTED)
-
- self.selecting = False
-
-
- def SelectAll(self):
- self.selecting = True
- for i in range(self.GetItemCount()):
- self.SetItemState(i, wx.LIST_STATE_SELECTED, wx.LIST_STATE_SELECTED)
-
- self.selecting = False
-
-
- def GetSelectedMsgs(self):
- ret = []
- index = self.GetFirstSelected()
- while index != -1:
- ret.append(self.itemDataMap[self.GetItemData(index)])
- index = self.GetNextSelected(index)
- return ret
-
-
- def GetFocusedMsg(self):
- focused = self.GetFocusedItem()
- if focused == -1:
- focused = self.GetFirstSelected()
-
- return self.itemDataMap[self.GetItemData(focused)]
-
-
- def MoveSelectionUp(self, deselect = True):
- if self.place is None:
- self.place = self.GetFocusedItem()
-
- next = self.GetNextItem(self.GetFocusedItem(), wx.LIST_NEXT_ABOVE)
- self.active_item = next
- if next > -1:
- self.DeselectAll()
- if deselect:
- self.place = None
- self.Select(next)
-
- self.Focus(next)
- self.EnsureVisible(next)
- if self.place is not None:
- start = min(self.place, self.GetFocusedItem())
- stop = max(self.place, self.GetFocusedItem()) + 1
- for i in xrange(start, stop):
- self.Select(i)
-
-
-
-
-
- def MoveSelectionDown(self, deselect = True):
- if self.place is None:
- self.place = self.GetFocusedItem()
-
- next = self.GetNextItem(self.GetFocusedItem(), wx.LIST_NEXT_BELOW)
- self.active_item = next
- if next > -1:
- self.DeselectAll()
- if deselect:
- self.place = None
- self.Select(next)
-
- self.Focus(next)
- self.EnsureVisible(next)
- if self.place is not None:
- start = min(self.place, self.GetFocusedItem())
- stop = max(self.place, self.GetFocusedItem()) + 1
- for i in xrange(start, stop):
- self.Select(i)
-
-
-
-
-
- def GetListCtrl(self):
- return self
-
-
- def GetSortImages(self):
- return (self.sm_dn, self.sm_up)
-
-
- def GetColumnText(self, index, col):
- item = list.GetItem(index, col)
- return item.GetText()
-
-
- def GetColumnSorter(self):
- '''Returns a callable object to be used for comparing column values when sorting.'''
- return self._SortedLC__ColumnSorter
-
-
- def __ColumnSorter(self, key1, key2):
- '''Like the wx.lib.mixins.listctrl.ColumnSorterMixin method, but
- case insensitive.'''
- col = self._col
- ascending = self._colSortFlag[col]
- item1 = self.itemDataMap[key1][col]
- item2 = self.itemDataMap[key2][col]
- if type(item1) == type('') or type(item2) == type(''):
- cmpVal = locale.strcoll(str(item1).lower(), str(item2).lower())
- else:
- cmpVal = cmp(item1, item2)
- if cmpVal == 0:
- cmpVal = apply(cmp, self.GetSecondarySortValues(col, key1, key2))
-
- if ascending:
- return cmpVal
- else:
- return -cmpVal
-
-
-
- class BoxPanel(wx.Panel):
-
- def __init__(self, parent, dir = wx.VERTICAL, style = 0):
- wx.Panel.__init__(self, parent, style = style)
- self.sizer = wx.BoxSizer(dir)
- self.SetSizer(self.sizer)
- self.Add = self.sizer.Add
- self.Layout = self.sizer.Layout
- self.ShowComp = self.sizer.Show
- self.HideComp = self.sizer.Hide
-
-
-
- class EvidenceWindow(wx.Dialog):
-
- def __init__(self, parent, msg, state):
- wx.Dialog.__init__(self, parent)
- self.state = state
- self.SetBackgroundColour(wx.WHITE)
- self.report = []
- score = float(msg[options[('Headers', 'score_header_name')]])
- distance = abs(0.5 - score)
- if distance <= distance:
- pass
- elif distance < 0.20000000000000001:
- strength = _('not very')
- elif distance <= distance:
- pass
- elif distance < 0.40000000000000002:
- strength = _('fairly')
- else:
- strength = _('very')
- label = _('SpamExperts was %s sure about this message, because:') % (strength,)
- self.evidence_box = wx.StaticBox(self, -1, label)
- self.bsizer = wx.StaticBoxSizer(self.evidence_box, wx.VERTICAL)
- evidence = msg[options[('Headers', 'evidence_header_name')]]
- if evidence:
- self.check_evidence(msg, evidence)
-
- self.border = wx.BoxSizer(wx.VERTICAL)
- classification = msg[options[('Headers', 'classification_header_name')]]
- if not msg['Subject']:
- pass
- subject = state.get_header(_('{no subject}'))
- if classification == options[('Headers', 'header_spam_string')]:
- label = _('This message (%s) was classified as Spam.') % (subject,)
- elif classification == options[('Headers', 'header_unsure_string')]:
- label = _('This message (%s) was classified as Unsure.') % (subject,)
- else:
- label = _('This message (%s) was classified as Not Spam.') % (subject,)
- self.add(label)
- self.SetTitle(subject + _(': Evidence'))
- self.check_training(evidence)
- self.border.Add(self.bsizer, 1, wx.EXPAND | wx.ALL, 10)
- self.SetSizer(self.border)
- self.ok = wx.Button(self, wx.ID_OK)
- self.copy = wx.Button(self, label = _('Copy evidence'))
- self.border.Add(self.copy, 0, wx.ALIGN_CENTER | wx.ALL, 5)
- self.border.Add(self.ok, 0, wx.ALIGN_CENTER | wx.ALL, 5)
- self.copy.Bind(wx.EVT_BUTTON, self.OnCopy)
- self.SetBestFittingSize()
-
-
- def OnCopy(self, evt):
- clip_text = wx.TextDataObject('\r\n'.join(self.report))
- if wx.TheClipboard.Open():
- wx.TheClipboard.SetData(clip_text)
- wx.TheClipboard.Flush()
- wx.TheClipboard.Close()
- dlg = wx.MessageDialog(self, _('Copied.'), _('Success'), wx.OK)
- else:
- dlg = wx.MessageDialog(self, _('Copy failed.'), _('Success'), wx.OK)
- dlg.ShowModal()
- dlg.Destroy()
-
-
- def check_evidence(self, msg, evidence):
- if self.check_address(evidence):
- return None
-
- if self.check_statistical(evidence):
- return None
-
- if self.check_fingerprint(evidence, msg):
- return None
-
- if self.check_dns(msg, evidence):
- return None
-
- self.add_evidence(_('No evidence was able to be found.'))
-
-
- def add(self, label):
- self.report.append(label)
- txt = wx.StaticText(self, -1, label)
- txt.SetBestFittingSize()
- self.border.Add(txt, 0, wx.ALIGN_LEFT | wx.ALL, 5)
-
-
- def add_evidence(self, label):
- self.report.append(label)
- txt = wx.StaticText(self, -1, label)
- self.bsizer.Add(txt, 0, wx.TOP | wx.LEFT, 10)
-
- address_re = re.compile("'address': (\\d\\.\\d+);?")
-
- def check_address(self, evidence):
- mo = self.address_re.search(evidence)
- if mo:
- address_score = float(mo.group(1))
- if address_score != 0.5:
- if address_score < 0.5:
- colour = _('whitelisted')
- else:
- colour = _('blacklisted')
- label = _('You have %s the address that this message is from.') % (colour,)
- self.add_evidence(label)
- return True
-
-
- return False
-
- stat_count_re = re.compile("'\\*HAMCOUNT\\*': (\\d+)\\.00;.*'\\*SPAMCOUNT\\*': (\\d+)\\.00;?", re.DOTALL)
-
- def check_training(self, evidence):
- mo = self.stat_count_re.search(evidence)
- if mo:
- hamcount = int(mo.group(1))
- spamcount = int(mo.group(2))
- if spamcount == spamcount:
- pass
- elif spamcount == 0:
- ratio = 1
- elif hamcount == 0:
- ratio = spamcount
- elif spamcount == 0:
- ratio = hamcount
- else:
- ratio = max(hamcount, spamcount) / min(hamcount, spamcount)
- total = hamcount + spamcount
- good = True
- if ratio <= ratio:
- pass
- elif ratio < 5:
- label = _('You have a good balance of Not Spam and Spam trained, ')
- elif ratio <= ratio:
- pass
- elif ratio < 10:
- label = _('Your training is a little imbalanced, ')
- elif ratio <= ratio:
- pass
- elif ratio < 50:
- label = _('Your training is very imbalanced, ')
- good = False
- else:
- label = _('Your training is extremely imbalanced, ')
- good = False
- if total <= total:
- pass
- elif total < 10:
- if good:
- label += _('but ')
- else:
- label += _('and ')
- label += _('your system needs more training before it will be effective.')
- elif total <= total:
- pass
- elif total < 1000:
- label += _('your system is well trained.')
- elif good:
- label += _('but ')
- else:
- label += _('and ')
- label += _('your system may be overtrained.')
- self.add(label)
-
-
- stats_re = re.compile("'statistical': (\\d\\.\\d+);?")
- token_re = re.compile('(?:(?:\'(.+?)\')|(?:"(.+?)")): (\\d.\\d+)', re.DOTALL)
- meta_tokens = ('address', 'statistical', '*H*', '*S*', '*HAMCOUNT*', '*SPAMCOUNT*', 'dns', 'fingerprint', 'RBL', 'SPF', 'DNS', 'SURBL', 'DomainKeys')
-
- def check_statistical(self, evidence):
- mo = self.stats_re.search(evidence)
- if mo:
- stats_score = float(mo.group(1))
- if stats_score != 0.5:
- distance = abs(0.5 - stats_score)
- if distance <= distance:
- pass
- elif distance < 0.20000000000000001:
- similiarity = _('a little')
- elif distance <= distance:
- pass
- elif distance < 0.40000000000000002:
- similiarity = _('somewhat')
- elif distance <= distance:
- pass
- elif distance <= 0.5:
- similiarity = _('a lot')
-
- if stats_score > 0.5:
- label = _('It looks %s like other Spam you have received.') % (similiarity,)
- else:
- label = _('It looks %s like other Not Spam you have received.') % (similiarity,)
- self.add_evidence(label)
- tokens = self.token_re.findall(evidence)
- tokens = _[1]
- tokens.sort()
- strong = []
- moderate = []
- weak = []
- for distance, token in tokens:
- if token.startswith('bi:'):
- token = token[3:]
-
- if distance < distance:
- pass
- elif distance < 0.10000000000000001:
- weak.append(token)
- continue
- if distance < distance:
- pass
- elif distance < 0.29999999999999999:
- moderate.append(token)
- continue
- if distance < distance:
- pass
- elif distance <= 0.5:
- strong.append(token)
- continue
-
- if strong:
- label = _('Strong clues included: ') + ','.join(strong)
- self.add_evidence(label)
-
- if moderate:
- label = _('Moderate clues included: ') + ','.join(moderate)
- self.add_evidence(label)
-
- if weak:
- label = _('Weak clues included: ') + ','.join(weak)
- self.add_evidence(label)
-
- return True
-
-
- return False
-
- fingerprint_re = re.compile("'fingerprint': (\\d\\.\\d+);?")
- ridges_re = re.compile('"FP:set\\(\\[([\\s\\d,\\\']*)\\]\\)": \\d+\\.\\d+;')
-
- def check_fingerprint(self, evidence, msg):
- mo = self.fingerprint_re.search(evidence)
- if mo:
- fp_score = float(mo.group(1))
- if fp_score != 0.5:
- if fp_score <= fp_score:
- pass
- elif fp_score < 0.80000000000000004:
- similiarity = _('a little')
- elif fp_score <= fp_score:
- pass
- elif fp_score < 0.90000000000000002:
- similiarity = _('somewhat')
- elif fp_score <= fp_score:
- pass
- elif fp_score <= 1.0:
- similiarity = _('a lot')
-
- label = _('It looked %s like Spam received by other SpamExperts users. Text in red matches other Spam messages.') % (similiarity,)
- self.add_evidence(label)
- mo = self.ridges_re.search(evidence)
- return True
-
-
- return False
-
- dns_re = re.compile("'dns': (\\d\\.\\d+);?")
-
- def check_dns(self, msg, evidence):
- mo = self.dns_re.search(evidence)
- if mo:
- dns_score = float(mo.group(1))
- if dns_score != 0.5:
- label = _('It came from a sender, or contained links, that other users have reported as Spam.')
- self.add_evidence(label)
- return True
-
-
- return False
-
-
-
- class SplitPanel(wx.SplitterWindow):
-
- def __init__(self, parent, model, ID = -1, style = wx.SP_LIVE_UPDATE):
- wx.SplitterWindow.__init__(self, parent, ID, style = style)
- self.sizer = wx.BoxSizer(wx.VERTICAL)
- self.SetSizer(self.sizer)
- self.Add = self.sizer.Add
- self.Layout = self.sizer.Layout
- self.ShowComp = self.sizer.Show
- self.HideComp = self.sizer.Hide
- self.model = model
-
-
- def ShowEvidence(self, evt):
- for id_list in self.list.GetSelectedMsgs():
- for corpus in (self.model.state.hamCorpus, self.model.state.spamCorpus, self.model.state.unsureCorpus):
-
- try:
- msg = corpus.get(id_list[3])
- except IOError:
- msg = None
-
- if msg is None:
- continue
-
-
- if msg is None:
- print >>sys.stderr, "Can't find message", id_list[3]
- continue
-
-
- try:
- msg.load()
- except IOError:
- print >>sys.stderr, "Can't load message", id_list[3]
- continue
-
- dlg = EvidenceWindow(self, msg, self.model.state)
- dlg.Show()
-
-
-
-
- class LabeledHyperlink(BoxPanel):
-
- def __init__(self, parent, label, linkName, url):
- BoxPanel.__init__(self, parent, wx.HORIZONTAL)
- self.label = wx.StaticText(self, label = label)
- self.Add(self.label)
- self.Add(hl.HyperLinkCtrl(self, -1, linkName, URL = url))
-
-
- def SetLabel(self, value):
- self.label.SetLabel(value)
- self.Layout()
-
-
-
- class ImgButton(wx.lib.buttons.GenBitmapTextToggleButton):
-
- def __init__(self, parent, text, imgs, handler = None):
- bmps = [
- None,
- None,
- None,
- None]
- if isinstance(imgs, types.TupleType):
- for idx in range(len(imgs)):
- bmps[idx] = imgs[idx].ConvertToBitmap()
-
- else:
- bmps[0] = imgs.ConvertToBitmap()
- wx.lib.buttons.GenBitmapTextToggleButton.__init__(self, parent, -1, bmps[0], text)
- self.SetBezelWidth(3)
- self.SetUseFocusIndicator(False)
- (self.bmpSelected, self.bmpDisabled, self.bmpFocus) = bmps[1:]
- self.handler = handler
- self.Bind(wx.EVT_BUTTON, self.OnButton)
-
-
- def OnButton(self, evt):
- if self.handler is not None:
- self.handler()
-
- evt.Skip()
-
-
- def _GetLabelSize(self):
- ''' used internally '''
- (w, h) = self.GetTextExtent(self.GetLabel())
- if not self.bmpLabel:
- return (w, h, True)
-
- w_bmp = self.bmpLabel.GetWidth() + 2
- h_bmp = self.bmpLabel.GetHeight() + 7
- height = h + h_bmp
- if w_bmp > w:
- width = w_bmp
- else:
- width = w
- return (width, height, True)
-
-
- def DrawLabel(self, dc, width, height, dw = 0, dy = 0):
- '''Draw label centered underneath image.'''
- bmp = self.bmpLabel
- if bmp != None:
- if self.bmpDisabled and not self.IsEnabled():
- bmp = self.bmpDisabled
-
- if self.bmpFocus and self.hasFocus:
- bmp = self.bmpFocus
-
- if self.bmpSelected and not (self.up):
- bmp = self.bmpSelected
-
- bw = bmp.GetWidth()
- bh = bmp.GetHeight()
- if not self.up:
- dw = dy = self.labelDelta
-
- hasMask = bmp.GetMask() != None
- else:
- bw = bh = 0
- dc.SetFont(self.GetFont())
- if self.IsEnabled():
- dc.SetTextForeground(self.GetForegroundColour())
- else:
- dc.SetTextForeground(wx.SystemSettings.GetColour(wx.SYS_COLOUR_GRAYTEXT))
- label = self.GetLabel()
- (tw, th) = dc.GetTextExtent(label)
- if not self.up:
- dw = dy = self.labelDelta
-
- pos_y = 10 + dy
- if bmp != None:
- dc.DrawBitmap(bmp, (width - bw) / 2 + dw, pos_y, hasMask)
- pos_y = pos_y + 2
-
- dc.DrawText(label, (width - tw) / 2 + dw, pos_y + bh)
-
-
-
- class LeftLabeledTF(BoxPanel):
-
- def __init__(self, parent, label = '', size = (-1, -1), validator = wx.DefaultValidator):
- BoxPanel.__init__(self, parent, wx.HORIZONTAL)
- self.label = wx.StaticText(self, label = label)
- self.tf = wx.TextCtrl(self, size = size, validator = validator)
- self.Add(self.label, 0, wx.ALIGN_CENTER | wx.ALL, 0)
- self.Add(self.tf, 1, wx.LEFT | wx.ALIGN_CENTER, 2)
-
-
- def SetLabel(self, value):
- self.label.SetLabel(value)
- self.Layout()
-
-
- def GetValue(self):
- return self.tf.GetValue()
-
-
- def SetValue(self, val):
- self.tf.SetValue(val)
-
-
- def Bind(self, *args):
- self.tf.Bind(*args)
-
-
-
- class LeftLabeledChoice(BoxPanel):
-
- def __init__(self, parent, label, choices):
- BoxPanel.__init__(self, parent, wx.HORIZONTAL)
- self.label = wx.StaticText(self, label = label)
- self.ch = wx.Choice(self, choices = choices)
- self.Add(self.label, 0, wx.ALIGN_CENTER | wx.ALL, 0)
- self.Add(self.ch, 1, wx.LEFT, 2)
-
-
- def SetLabel(self, value):
- self.label.SetLabel(value)
- self.Layout()
-
-
- def GetSelection(self):
- return self.ch.GetStringSelection()
-
-
- def SetStringSelection(self, val):
- self.ch.SetStringSelection(val)
-
-
-
- class StaticBoxGrid(wx.Panel):
-
- def __init__(self, parent, dir = wx.VERTICAL, style = 0, title = 'No Title'):
- wx.Panel.__init__(self, parent, style = style)
- self.innerSizer = wx.GridBagSizer(0, 0)
- self.box = wx.StaticBox(self, label = title)
- self.sizer = wx.StaticBoxSizer(self.box, dir)
- self.sizer.Add(self.innerSizer, 1, wx.EXPAND)
- self.SetSizer(self.sizer)
-
-
- def SetTitle(self, value):
- self.box.SetLabel(value)
-
-
- def Add(self, *args, **kargs):
- self.innerSizer.Add(*args, **kargs)
-
-
- def Layout(self):
- self.innerSizer.Layout()
-
-
-
- def List2Menu(parent, list):
- menu = wx.Menu()
- for item in list:
- if item:
- (menuName, handler) = item
- id = wx.NewId()
- menu.Append(id, menuName)
- parent.Bind(wx.EVT_MENU, handler, id = id)
- continue
- menu.AppendSeparator()
-
- return menu
-
-